/*
 * 工作流活动 - 人员权限检查任务
 * 
 * 主要功能：
 * - 检查指定用户是否具有ManagePersons权限
 * - 作为工作流活动在Orchard Core工作流系统中使用
 * - 提供权限检查的结果输出
 * - 支持本地化显示
 */

using Lombiq.TrainingDemo.Permissions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Localization;
using OrchardCore.Users.Models;
using OrchardCore.Users.Services;
using OrchardCore.Workflows.Abstractions.Models;
using OrchardCore.Workflows.Activities;
using OrchardCore.Workflows.Models;
using OrchardCore.Workflows.Services;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Lombiq.TrainingDemo.Activities;

/// <summary>
/// 人员权限检查任务 - 工作流活动
/// 
/// 主要用途：
/// - 检查指定用户是否具有ManagePersons权限
 /* - 作为工作流活动在Orchard Core工作流系统中使用
 * - 提供权限检查的结果输出
 * - 支持本地化显示
 * 
 * 使用场景：
 * - 在工作流中检查用户权限
 * - 根据权限结果执行不同分支
 * - 自动化权限验证流程
 * 
 * 设计原因：
 * - 提供可重用的权限检查活动
 * - 集成到Orchard Core工作流系统
 * - 支持动态权限验证
 * 
 * 设计模式：
 * - 活动模式：继承TaskActivity实现工作流活动
 * - 依赖注入模式：通过构造函数注入所需服务
 * - 表达式模式：使用WorkflowExpression处理动态输入
 * - 结果模式：返回预定义的结果集
/// </summary>
// 一个简单的工作流任务，接受用户名作为TextField输入，并检查用户是否具有ManagePersons权限。
 */
public class ManagePersonsPermissionCheckerTask : TaskActivity
{
    private readonly IAuthorizationService _authorizationService;
    private readonly IUserService _userService;
    private readonly IWorkflowExpressionEvaluator _expressionEvaluator;
    private readonly IStringLocalizer S;

    /// <summary>
    /// 构造函数 - 注入所需的服务依赖
    /// </summary>
    /// <param name="authorizationService">授权服务，用于权限检查</param>
    /// <param name="userService">用户服务，用于获取用户信息</param>
    /// <param name="expressionEvaluator">表达式求值器，用于处理工作流表达式</param>
    /// <param name="localizer">本地化器，用于多语言支持</param>
    public ManagePersonsPermissionCheckerTask(
        IAuthorizationService authorizationService,
        IUserService userService,
        IWorkflowExpressionEvaluator expressionEvaluator,
        IStringLocalizer<ManagePersonsPermissionCheckerTask> localizer)
    {
        _authorizationService = authorizationService;
        _userService = userService;
        _expressionEvaluator = expressionEvaluator;
        S = localizer;
    }

    /// <summary>
    /// 活动的技术名称
    /// 
    /// 功能说明：
    /// - 工作流定义中的活动引用此名称
    /// - 用于唯一标识此活动
    /// </summary>
    public override string Name => nameof(ManagePersonsPermissionCheckerTask);

    /// <summary>
    /// 活动的显示名称
    /// 
    /// 功能说明：
    /// - 支持本地化显示
    /// - 在工作流设计器中显示的名称
    /// </summary>
    public override LocalizedString DisplayText => S["Manage Persons Permission Checker Task"];

    /// <summary>
    /// 活动所属的类别
    /// 
    /// 功能说明：
    /// - 活动选择器按此类别对活动进行分组
    /// - 用于组织和管理工作流活动
    /// </summary>
    public override LocalizedString Category => S["User"];

    /// <summary>
    /// 要检查ManagePersons权限的用户名
    /// 
    /// 功能说明：
    /// - 使用WorkflowExpression支持动态表达式
    /// - 可以在工作流中动态设置用户名
    /// </summary>
    public WorkflowExpression<string> UserName
    {
        get => GetProperty(() => new WorkflowExpression<string>());
        set => SetProperty(value);
    }

    /// <summary>
    /// 返回此活动的可能结果
    /// 
    /// 功能说明：
    /// - 定义活动的输出结果
    /// - 支持本地化显示结果名称
    /// 
    /// 返回结果：
    /// - HasPermission：用户具有权限
    /// - NoPermission：用户没有权限
    /// </summary>
    /// <param name="workflowContext">工作流执行上下文</param>
    /// <param name="activityContext">活动上下文</param>
    /// <returns>可能的结果集合</returns>
    public override IEnumerable<Outcome> GetPossibleOutcomes(
        WorkflowExecutionContext workflowContext,
        ActivityContext activityContext) =>
        Outcomes(S["HasPermission"], S["NoPermission"]);

    /// <summary>
    /// 执行活动的主要逻辑
    /// 
    /// 功能说明：
    /// - 获取要检查的用户名
    /// - 查找用户并创建用户主体
    /// - 检查用户是否具有ManagePersons权限
    /// - 返回相应的结果
    /// 
    /// 执行流程：
    /// 1. 评估用户名表达式
    /// 2. 通过用户服务获取用户
    /// 3. 创建用户主体
    /// 4. 使用授权服务检查权限
    /// 5. 返回相应的结果
    /// </summary>
    /// <param name="workflowContext">工作流执行上下文</param>
    /// <param name="activityContext">活动上下文</param>
    /// <returns>活动执行结果</returns>
    public override async Task<ActivityExecutionResult> ExecuteAsync(
        WorkflowExecutionContext workflowContext,
        ActivityContext activityContext)
    {
        // 评估用户名表达式
        var userName = await _expressionEvaluator.EvaluateAsync(UserName, workflowContext, encoder: null);
        var user = (User)await _userService.GetUserAsync(userName);

        if (user != null)
        {
            // 创建用户主体
            var userClaim = await _userService.CreatePrincipalAsync(user);

            // 检查用户是否具有ManagePersons权限
            if (await _authorizationService.AuthorizeAsync(userClaim, PersonPermissions.ManagePersons))
            {
                return Outcomes("HasPermission");
            }
        }

        return Outcomes("NoPermission");
    }
}

// 下一站：现在您必须为ActivityDisplayDriver创建一个ViewModel。查看以下文件并回到这里。
// ViewModels/ManagePersonsPermissionCheckerTaskViewModel.cs

// 下一站：Drivers/ManagePersonsPermissionCheckerTaskDisplayDriver.cs
